﻿/*
 * iec104.cpp
 *
 *  Created on: 2017年3月20日
 *      Author: work
 */

#include <dm/export.hpp>

#define DM_API_PROTOCOL DM_API_EXPORT

#include <dm/protocol/iec104.hpp>
#include <dm/os/log/logger.hpp>
#include <ctime>
#include <cstdio>
#include <cstdlib>

namespace dm{
namespace protocol{

static const char* logModule = "CIec104.protocol.dm";

CIec104::CIec104():CProtocol(),m_ssq(),m_rsq(),m_ssqCfm(),m_rsqCfm(),m_lastConffedTime(),m_lastSendConfirmTime(),
		m_lastRecvDataTime(),m_ifTestingLink(false),m_errFrameCount(0),
		m_dtStarted(false),m_autoStartDt(false),m_ifStartingDt(false),
		m_commonAddr(1),m_baseOfYx(1),m_baseOfYc(16385),m_baseOfYk(24577),m_baseOfKwh(25601),
		m_rxFrame(NULL),m_txFrame(NULL),m_k(12),m_w(8),m_t0(30),m_t1(15),m_t2(10),m_t3(20){
	log().debug(THISMODULE "创建对象");
}

CIec104::~CIec104(){
	if( m_rxFrame )
		delete m_rxFrame;
	if( m_txFrame )
		delete m_txFrame;

	log().debug(THISMODULE "销毁对象");
}

CIec104::frame_t& CIec104::getRxFrame(){
	if( !m_rxFrame ){
		m_rxFrame = genRxTempFrame();
		log().info(THISMODULE "创建接收帧对象");
	}

	return *m_rxFrame;
}

const CIec104::frame_t& CIec104::getTxFrame(){
	if( !m_txFrame ){
		m_txFrame = genTxTempFrame();
		log().info(THISMODULE "创建发送帧对象");
	}

	return *m_txFrame;
}

bool CIec104::setLenOfAsduAddr( dm::uint8 l ){
	if( !m_txFrame ){
		m_txFrame = genTxTempFrame();
		log().info(THISMODULE "创建发送帧对象");
	}

	if( !m_rxFrame ){
		m_rxFrame = genRxTempFrame();
		log().info(THISMODULE "创建接收帧对象");
	}

	return m_txFrame->getApdu().setLenOfCommonAddr(l) && m_rxFrame->getApdu().setLenOfCommonAddr(l);
}

bool CIec104::setLenOfInfoAddr( dm::uint8 l ){
	if( !m_txFrame ){
		m_txFrame = genTxTempFrame();
		log().info(THISMODULE "创建发送帧对象");
	}

	if( !m_rxFrame ){
		m_rxFrame = genRxTempFrame();
		log().info(THISMODULE "创建接收帧对象");
	}

	return m_txFrame->getApdu().setLenOfObjAddr(l) && m_rxFrame->getApdu().setLenOfObjAddr(l);
}

bool CIec104::setLenOfTransCause( dm::uint8 l ){
	if( !m_txFrame ){
		m_txFrame = genTxTempFrame();
		log().info(THISMODULE "创建发送帧对象");
	}

	if( !m_rxFrame ){
		m_rxFrame = genRxTempFrame();
		log().info(THISMODULE "创建接收帧对象");
	}

	return m_txFrame->getApdu().setLenOfCause(l) && m_rxFrame->getApdu().setLenOfCause(l);
}

void CIec104::setMaxLenOfApdu( dm::uint16 l ){
	if( !m_txFrame ){
		m_txFrame = genTxTempFrame();
		log().info(THISMODULE "创建发送帧对象");
	}

	if( !m_rxFrame ){
		m_rxFrame = genRxTempFrame();
		log().info(THISMODULE "创建接收帧对象");
	}

	m_txFrame->getApdu().setMaxLenOfApdu(l);
	m_rxFrame->getApdu().setMaxLenOfApdu(l);
}

CIec104::frame_104_t* CIec104::genRxTempFrame(){
	return new frame_104_t;
}

CIec104::frame_104_t* CIec104::genTxTempFrame(){
	return new frame_104_t;
}

/**
 * 104定时任务。
 * 包含了104链路处理及任务状态机
 * @param txFrame
 * @return
 */
CIec104::EAction CIec104::timedRefresh( const ts_t& ts,const rts_t& rts ){
	if( ifCanSendIFrame() ){
		txFrame().setIFrame();
		EAction action = CProtocol::timedRefresh(ts,rts);
		if( action==Action_Send || action==Action_SendAndReTime ){
			setUpIFrame(ts,rts);
			return action;
		}
	}

	return taskLink(ts,rts);
}

/**
 * 链路维护任务
 * @param tf
 * @return
 */
CIec104::EAction CIec104::taskLink( const ts_t& ts,const rts_t& rts ){
	dm::uint16 rsqUncfm = m_rsqCfm - m_rsq;

	// 是否需要立即对接收到的帧进行确认
	if( rsqUncfm>m_w || (rsqUncfm>1 && m_lastSendConfirmTime.isTimeout_sec(m_t3,rts) ) ){
		m_lastSendConfirmTime = rts;
		return needConfirmRsq();
	}

	// 是否对端长时间没有确认
	if( m_ssqCfm!=m_ssq && m_lastConffedTime.isTimeout_sec(m_t1,rts) ){
		log().warnning(ts,THISMODULE "对端长时间不确认帧序号 %d->%d",m_ssqCfm.v(),m_ssq.v());
		return Action_CloseLink;
	}

	if( m_autoStartDt ){
		if( isSendBeforeRecv() && m_ifStartingDt )
			m_ifStartingDt = false;

		if( !m_dtStarted && !m_ifStartingDt ){
			log().info(ts,THISMODULE "启动数据传输");
			txFrame().setUFrame();
			txFrame().setStartDt_avaliable(true);
			m_ifStartingDt = true;
			return Action_SendAndReTime;
		}
	}

	// 是否需要发送测试帧
	if( m_lastRecvTime.isTimeout_sec(m_t2,rts) ){
		if( m_ifTestingLink ){
			if( m_lastSendTime.isTimeout_sec(m_t1,rts) ){
				log().warnning(ts,THISMODULE "测试帧无响应 %d,关闭链路.",m_t1);
				return Action_CloseLink;
			}else{
				// 等待链路测试应答
				return Action_Nothing;
			}
		}else{
			log().debug(ts,THISMODULE "长时间未收到对端报文 %d",m_t2);
			return linkTest();
		}
	}

	return Action_Nothing;
}

CIec104::EAction CIec104::dealRxFrame( const ts_t& ts,const rts_t& rts ){
	if( rxFrame().isIFrame() ){
		if( m_dtStarted ){
			return dealRxIFrame(ts,rts);
		}else{
			log().warnning( ts,THISMODULE "收到I帧，但是目前数据传输没有开启");
		}
	}else if( rxFrame().isSFrame() )
		dealRxSFrame(rxFrame().getRecvSeq(),ts,rts);
	else if( rxFrame().isUFrame() )
		return dealRxUFrame(ts,rts);

	return timedRefresh(ts,rts);
}

void CIec104::reset( const ts_t& ts,const rts_t& rts ){
	log().debug( ts,THISMODULE "复位");
	CProtocol::reset(ts,rts);
	m_dtStarted = false;

	m_ssq = 0;
	m_rsq = 0;
	m_ssqCfm	= m_ssq;
	m_rsqCfm = m_rsq;

	m_errFrameCount = 0;
	m_lastConffedTime = rts;
	m_lastSendConfirmTime = rts;
	m_lastRecvDataTime = rts;

	m_ifTestingLink	= false;
	m_ifStartingDt = false;
}

bool CIec104::setTask_call( const ts_t& ts,const rts_t& rts,const group_t& group,const sec_t& timeout ){
	if( isDtStoped() ){
		log().warnning( ts,THISMODULE "数据传输未开启");
		return false;
	}

	return CProtocol::setTask_call(ts,rts,group,timeout);
}

bool CIec104::setTask_syncClock( const ts_t& ts,const rts_t& rts,const sec_t& timeout ){
	if( isDtStoped() ){
		log().warnning( ts,THISMODULE "数据传输未开启");
		return false;
	}

	return CProtocol::setTask_syncClock(ts,rts,timeout);
}

bool CIec104::setTask_remoteControl( const ts_t& ts,const rts_t& rts,const rmtctl_t& rc,const index_t& addr,const sec_t& timeout ){
	if( isDtStoped() ){
		log().warnning( ts,THISMODULE "数据传输未开启");
		return false;
	}

	return CProtocol::setTask_remoteControl(ts,rts,rc,addr,timeout);
}

bool CIec104::setTask_parasSetUint8( const ts_t& ts,const rts_t& rts,const index_t& addr,const index_t& size,const dm::uint8* data,const sec_t& timeout ){
	if( isDtStoped() ){
		log().warnning( ts,THISMODULE "数据传输未开启");
		return false;
	}

	return CProtocol::setTask_parasSetUint8(ts,rts,addr,size,data,timeout);
}

bool CIec104::setTask_parasSetInt8( const ts_t& ts,const rts_t& rts,const index_t& addr,const index_t& size,const dm::int8* data,const sec_t& timeout ){
	if( isDtStoped() ){
		log().warnning( ts,THISMODULE "数据传输未开启");
		return false;
	}

	return CProtocol::setTask_parasSetInt8(ts,rts,addr,size,data,timeout);
}

bool CIec104::setTask_parasSetUint16( const ts_t& ts,const rts_t& rts,const index_t& addr,const index_t& size,const dm::uint16* data,const sec_t& timeout ){
	if( isDtStoped() ){
		log().warnning( ts,THISMODULE "数据传输未开启");
		return false;
	}

	return CProtocol::setTask_parasSetUint16(ts,rts,addr,size,data,timeout);
}

bool CIec104::setTask_parasSetInt16( const ts_t& ts,const rts_t& rts,const index_t& addr,const index_t& size,const dm::int16* data,const sec_t& timeout ){
	if( isDtStoped() ){
		log().warnning( ts,THISMODULE "数据传输未开启");
		return false;
	}

	return CProtocol::setTask_parasSetInt16(ts,rts,addr,size,data,timeout);
}

bool CIec104::setTask_parasSetUint32( const ts_t& ts,const rts_t& rts,const index_t& addr,const index_t& size,const dm::uint32* data,const sec_t& timeout ){
	if( isDtStoped() ){
		log().warnning( ts,THISMODULE "数据传输未开启");
		return false;
	}

	return CProtocol::setTask_parasSetUint32(ts,rts,addr,size,data,timeout);
}

bool CIec104::setTask_parasSetInt32( const ts_t& ts,const rts_t& rts,const index_t& addr,const index_t& size,const dm::int32* data,const sec_t& timeout ){
	if( isDtStoped() ){
		log().warnning( ts,THISMODULE "数据传输未开启");
		return false;
	}

	return CProtocol::setTask_parasSetInt32(ts,rts,addr,size,data,timeout);
}

bool CIec104::setTask_parasSetUint64( const ts_t& ts,const rts_t& rts,const index_t& addr,const index_t& size,const dm::uint64* data,const sec_t& timeout ){
	if( isDtStoped() ){
		log().warnning( ts,THISMODULE "数据传输未开启");
		return false;
	}

	return CProtocol::setTask_parasSetUint64(ts,rts,addr,size,data,timeout);
}

bool CIec104::setTask_parasSetInt64( const ts_t& ts,const rts_t& rts,const index_t& addr,const index_t& size,const dm::int64* data,const sec_t& timeout ){
	if( isDtStoped() ){
		log().warnning( ts,THISMODULE "数据传输未开启");
		return false;
	}

	return CProtocol::setTask_parasSetInt64(ts,rts,addr,size,data,timeout);
}

bool CIec104::setTask_parasSetFloat32( const ts_t& ts,const rts_t& rts,const index_t& addr,const index_t& size,const dm::float32* data,const sec_t& timeout ){
	if( isDtStoped() ){
		log().warnning( ts,THISMODULE "数据传输未开启");
		return false;
	}

	return CProtocol::setTask_parasSetFloat32(ts,rts,addr,size,data,timeout);
}

bool CIec104::setTask_parasSetFloat64( const ts_t& ts,const rts_t& rts,const index_t& addr,const index_t& size,const dm::float64* data,const sec_t& timeout ){
	if( isDtStoped() ){
		log().warnning( ts,THISMODULE "数据传输未开启");
		return false;
	}

	return CProtocol::setTask_parasSetFloat64(ts,rts,addr,size,data,timeout);
}

bool CIec104::setTask_parasGet( const ts_t& ts,const rts_t& rts,const index_t& addr,const index_t& size,const sec_t& timeout ){
	if( isDtStoped() ){
		log().warnning( ts,THISMODULE "数据传输未开启");
		return false;
	}

	return CProtocol::setTask_parasGet(ts,rts,addr,size,timeout);
}

bool CIec104::setTask_syncData( const ts_t& ts,const rts_t& rts,const sync_t& type,const sec_t& timeout ){
	if( isDtStoped() ){
		log().warnning( ts,THISMODULE "数据传输未开启");
		return false;
	}

	return CProtocol::setTask_syncData(ts,rts,type,timeout);
}

CIec104::EAction CIec104::sendIFrame_error( const frame_apdu_t& rf,frame_apdu_t& tf,const frame_apdu_t::ECause& casue ){
	tf = rf;
	tf.setCauseOfTrans( casue );
	return Action_SendAndReTime;
}

CIec104::EAction CIec104::sendUFrame_startDt(){
	txFrame().setUFrame();
	txFrame().setStartDt_avaliable(true);
	return Action_SendAndReTime;
}

void CIec104::setUpIFrame( const ts_t& ts,const rts_t& rts ){
	txFrame().getApdu().setCommonAddress(m_commonAddr);

	// 设置序号
	setSendSeq();
	setRecvConfSeq(ts,rts);
}

bool CIec104::ifNeedSendSFrame()const{
	return m_rsqCfm!=m_rsq;
}

CIec104::EAction CIec104::linkTest(){
	if( m_ifTestingLink )
		return Action_CloseLink;
	m_ifTestingLink = true;
	txFrame().setUFrame();
	txFrame().setTestFr_avaliable(true);

	return Action_SendAndReTime;
}

CIec104::EAction CIec104::dealRxUFrame( const ts_t& ts,const rts_t& rts ){
	txFrame().setUFrame();
	if( rxFrame().isTestFr_avaliable() ){
		return dealTestFr(ts,rts);
	}else if( rxFrame().isStopDt_avaliable() ){
		return dealStopDt(ts,rts);
	}else if( rxFrame().isStartDt_avaliable() ){
		return dealStartDt(ts,rts);
	}else if( rxFrame().isStopDt_confirm() ){
		return dealStopDtConf(ts,rts);
	}else if( rxFrame().isStartDt_confirm() ){
		return dealStartDtConf(ts,rts);
	}else if( rxFrame().isTestFr_confirm() ){
		m_ifTestingLink = false;
		return Action_Nothing;
	}else{
		return Action_Nothing;
	}

	return Action_SendAndReTime;
}

/**
 * 处理接收到的S帧
 * @param seq
 * @param
 * @param rts
 */
void CIec104::dealRxSFrame( const count_t& seq,const ts_t& ts,const rts_t& rts ){
	log().debug( ts,THISMODULE "收到有效的确认帧%d->%d",m_ssqCfm.v(),seq.v());
	m_ssqCfm = seq;
	m_lastConffedTime =rts;
}

/**
 * 处理接收到I帧
 * @param rxFrame
 * @param txFrame
 * @return
 */
CIec104::EAction CIec104::dealRxIFrame( const ts_t& ts,const rts_t& rts ){
	if( rxFrame().getSendSeq()!=m_rsq ){
		log().warnning( ts,THISMODULE "收到的发送序号错误(%d),应该是%d",rxFrame().getSendSeq(),m_rsq.v() );
		return Action_Nothing;
	}

	if( !rxFrame().getApdu().checkCommonAddress(m_commonAddr) ){
		log().warnning( ts,THISMODULE "检测公共地址失败.本地%04X,%04X",m_commonAddr, rxFrame().getApdu().getCommonAddress() );
		return Action_Nothing;
	}

	++m_rsq;
	m_ssqCfm = rxFrame().getRecvSeq();
	m_lastConffedTime = rts;

	txFrame().setIFrame();

	EAction action = dealAsdu( rxFrame().getApdu(),txFrame().getApdu(),ts,rts);
	if( action==Action_SendAndReTime || action==Action_Send )
		setUpIFrame(ts,rts);

	return action;
}

CIec104::EAction CIec104::dealTestFr( const ts_t& ts,const rts_t& /*rts*/ ){
	log().debug( ts,THISMODULE "收到测试链路帧");
	txFrame().setUFrame();
	txFrame().setTestFr_confirm(true);

	return Action_SendAndReTime;
}

CIec104::EAction CIec104::askTestFr( const ts_t& ts,const rts_t& /*rts*/ ){
	log().debug( ts,THISMODULE "发送测试链路帧");
	m_ifTestingLink = true;

	txFrame().setUFrame();
	txFrame().setTestFr_avaliable(true);

	return Action_SendAndReTime;
}

CIec104::EAction CIec104::dealAsdu( const frame_apdu_t& rf,frame_apdu_t& tf,const ts_t& ts,const rts_t& rts ){
	log().debug( ts,THISMODULE "id：%d",rf.getType());

	switch( rf.getType() ){
	case frame_apdu_t::M_SP_NA_1: // 单点信息
		return dealAsdu_M_SP_NA_1(rf,tf,ts,rts);

	case frame_apdu_t::M_DP_NA_1: // 双点信息
		return dealAsdu_M_DP_NA_1(rf,tf,ts,rts);

	case frame_apdu_t::M_ST_NA_1:	// 步位置信息
		return dealAsdu_M_ST_NA_1(rf,tf,ts,rts);

	case frame_apdu_t::M_BO_NA_1:	// 32 比特串
		return dealAsdu_M_BO_NA_1(rf,tf,ts,rts);

	case frame_apdu_t::M_ME_NA_1: // 测量值，规一化值
		return dealAsdu_M_ME_NA_1(rf,tf,ts,rts);

	case frame_apdu_t::M_ME_NB_1: // 测量值，标度化值
		return dealAsdu_M_ME_NB_1(rf,tf,ts,rts);

	case frame_apdu_t::M_ME_NC_1: // 测量值，短浮点数
		return dealAsdu_M_ME_NC_1(rf,tf,ts,rts);

	case frame_apdu_t::M_IT_NA_1: // 累计量
		return dealAsdu_M_IT_NA_1(rf,tf,ts,rts);

	case frame_apdu_t::M_PS_NA_1: // 带状态检出的成组单点信息
		return dealAsdu_M_PS_NA_1(rf,tf,ts,rts);

	case frame_apdu_t::M_ME_ND_1: // 不带品质描述的规一化测量值
		return dealAsdu_M_ME_ND_1(rf,tf,ts,rts);

	case frame_apdu_t::M_SP_TB_1: // 带时标CP56Time2a 的单点信息
		return dealAsdu_M_SP_TB_1(rf,tf,ts,rts);

	case frame_apdu_t::M_DP_TB_1: // 带时标CP56Time2a 的双点信息
		return dealAsdu_M_DP_TB_1(rf,tf,ts,rts);

	case frame_apdu_t::M_ST_TB_1: // 带时标CP56Time2a 的步位置信息
		return dealAsdu_M_ST_TB_1(rf,tf,ts,rts);

	case frame_apdu_t::M_BO_TB_1: // 带时标CP56Time2a 的32 比特串
		return dealAsdu_M_BO_TB_1(rf,tf,ts,rts);

	case frame_apdu_t::M_ME_TD_1: // 带时标CP56Time2a 的测量值，规一化值
		return dealAsdu_M_ME_TD_1(rf,tf,ts,rts);

	case frame_apdu_t::M_ME_TE_1: // 带时标CP56Time2a 的测量值，标度化值
		return dealAsdu_M_ME_TE_1(rf,tf,ts,rts);

	case frame_apdu_t::M_ME_TF_1: // 带时标CP56Time2a 的测量值，短浮点数
		return dealAsdu_M_ME_TF_1(rf,tf,ts,rts);

	case frame_apdu_t::M_IT_TB_1: // 带时标CP56Time2a 的累计量
		return dealAsdu_M_IT_TB_1(rf,tf,ts,rts);

	case frame_apdu_t::M_EP_TD_1: // 带时标CP56Time2a 的继电保护装置事件
		return dealAsdu_M_EP_TD_1(rf,tf,ts,rts);

	case frame_apdu_t::M_EP_TE_1: // 带时标CP56Time2a 的继电保护装置成组启动事件
		return dealAsdu_M_EP_TE_1(rf,tf,ts,rts);

	case frame_apdu_t::M_EP_TF_1: // 带时标CP56Time2a 的继电保护装置成组出口信息
		return dealAsdu_M_EP_TF_1(rf,tf,ts,rts);

		// 控制方向
	case frame_apdu_t::C_SC_NA_1:	// 单命令
		return dealAsdu_C_SC_NA_1(rf,tf,ts,rts);

	case frame_apdu_t::C_DC_NA_1: // 双命令
		return dealAsdu_C_DC_NA_1(rf,tf,ts,rts);

	case frame_apdu_t::C_RC_NA_1: // 升降命令
		return dealAsdu_C_RC_NA_1(rf,tf,ts,rts);

	case frame_apdu_t::C_SE_NA_1: // 设点命令，规一化值
		return dealAsdu_C_SE_NA_1(rf,tf,ts,rts);

	case frame_apdu_t::C_SE_NB_1: // 设点命令，标度化值
		return dealAsdu_C_SE_NB_1(rf,tf,ts,rts);

	case frame_apdu_t::C_SE_NC_1: // 设点命令，短浮点数
		return dealAsdu_C_SE_NC_1(rf,tf,ts,rts);

	case frame_apdu_t::C_BO_NA_1: // 32 比特串
		return dealAsdu_C_BO_NA_1(rf,tf,ts,rts);

	case frame_apdu_t::C_SC_NA_1_7: // 带时标CP56Time2a 的单命令
		return dealAsdu_C_SC_NA_1_7(rf,tf,ts,rts);

	case frame_apdu_t::C_DC_NA_1_7: // 带时标CP56Time2a 的双命令
		return dealAsdu_C_DC_NA_1_7(rf,tf,ts,rts);

	case frame_apdu_t::C_RC_NA_1_7: // 带时标CP56Time2a 的升降命令
		return dealAsdu_C_RC_NA_1_7(rf,tf,ts,rts);

	case frame_apdu_t::C_SE_TA_1_7: // 带时标CP56Time2a 的设点命令，规一化值
		return dealAsdu_C_SE_TA_1_7(rf,tf,ts,rts);

	case frame_apdu_t::C_SE_TB_1_7: // 带时标CP56Time2a 的设点命令，标度化值
		return dealAsdu_C_SE_TB_1_7(rf,tf,ts,rts);

	case frame_apdu_t::C_SE_TC_1_7: // 带时标CP56Time2a 的设点命令，短浮点数
		return dealAsdu_C_SE_TC_1_7(rf,tf,ts,rts);

	case frame_apdu_t::C_BO_NA_1_7: // 带时标CP56Time2a 的32 比特串
		return dealAsdu_C_BO_NA_1_7(rf,tf,ts,rts);

	case frame_apdu_t::M_EI_NA_1: // 初始化结束
		return dealAsdu_M_EI_NA_1(rf,tf,ts,rts);

	case frame_apdu_t::C_IC_NA_1: // 总召唤命令
		return dealAsdu_C_IC_NA_1(rf,tf,ts,rts);

	case frame_apdu_t::C_CI_NA_1: // 电能脉冲召唤命令
		return dealAsdu_C_CI_NA_1(rf,tf,ts,rts);

	case frame_apdu_t::C_RD_NA_1: // 读命令
		return dealAsdu_C_RD_NA_1(rf,tf,ts,rts);

	case frame_apdu_t::C_CS_NA_1: // 时钟同步命令
		return dealAsdu_C_CS_NA_1(rf,tf,ts,rts);

	case frame_apdu_t::C_RP_NA_1: // 复位进程命令
		return dealAsdu_C_RP_NA_1(rf,tf,ts,rts);

	case frame_apdu_t::C_TS_NA_1: // 带时标CP56Time2a 的测试命令
		return dealAsdu_C_TS_NA_1(rf,tf,ts,rts);

	case frame_apdu_t::P_ME_NA_1: // 测量值参数，规一化值
		return dealAsdu_P_ME_NA_1(rf,tf,ts,rts);

	case frame_apdu_t::P_ME_NB_1: // 测量值参数，标度化值
		return dealAsdu_P_ME_NB_1(rf,tf,ts,rts);

	case frame_apdu_t::P_ME_NC_1: // 测量值参数，短浮点数
		return dealAsdu_P_ME_NC_1(rf,tf,ts,rts);

	case frame_apdu_t::P_AC_NA_1: // 参数激活
		return dealAsdu_P_AC_NA_1(rf,tf,ts,rts);

	case frame_apdu_t::F_FR_NA_1: // 文件已准备好
		return dealAsdu_F_FR_NA_1(rf,tf,ts,rts);

	case frame_apdu_t::F_SR_NA_1: // 节已准备好
		return dealAsdu_F_SR_NA_1(rf,tf,ts,rts);

	case frame_apdu_t::F_SC_NA_1: // 召唤目录，选择文件，召唤文件，召唤节
		return dealAsdu_F_SC_NA_1(rf,tf,ts,rts);

	case frame_apdu_t::F_LS_NA_1: // 最后的节，最后的段
		return dealAsdu_F_LS_NA_1(rf,tf,ts,rts);

	case frame_apdu_t::F_AF_NA_1: // 确认文件，确认节
		return dealAsdu_F_AF_NA_1(rf,tf,ts,rts);

	case frame_apdu_t::F_SG_NA_1: // 段
		return dealAsdu_F_SG_NA_1(rf,tf,ts,rts);

	case frame_apdu_t::F_DR_NA_1: // 目录
		return dealAsdu_F_DR_NA_1(rf,tf,ts,rts);

	default:
		log().warnning( ts,THISMODULE "不支持的类型%d",rf.getType() );
		return Action_Nothing;
	}

	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_M_SP_NA_1( const frame_apdu_t& ,frame_apdu_t& ,const ts_t& ts,const rts_t& /*rts*/ ){
	log().warnning( ts,THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_M_DP_NA_1( const frame_apdu_t& /*rf*/,frame_apdu_t&,const ts_t& ts,const rts_t& /*rts*/ ){
	log().warnning( ts,THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_M_ST_NA_1( const frame_apdu_t&,frame_apdu_t&,const ts_t& ts,const rts_t& /*rts*/ ){
	log().warnning( ts,THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_M_BO_NA_1( const frame_apdu_t&,frame_apdu_t& ,const ts_t& ts,const rts_t& /*rts*/ ){
	log().warnning( ts,THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_M_ME_NA_1( const frame_apdu_t&,frame_apdu_t&,const ts_t& ts,const rts_t& /*rts*/ ){
	log().warnning( ts,THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_M_ME_NB_1( const frame_apdu_t& /*rf*/,frame_apdu_t&,const ts_t& ts,const rts_t& /*rts*/ ){
	log().warnning( ts,THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_M_ME_NC_1( const frame_apdu_t& /*rf*/,frame_apdu_t&,const ts_t& ts,const rts_t& /*rts*/ ){
	log().warnning( ts,THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_M_IT_NA_1( const frame_apdu_t& /*rf*/,frame_apdu_t&,const ts_t& ts,const rts_t& /*rts*/ ){
	log().warnning( ts,THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_M_PS_NA_1( const frame_apdu_t&,frame_apdu_t&,const ts_t& ts,const rts_t& /*rts*/ ){
	log().warnning( ts,THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_M_ME_ND_1( const frame_apdu_t&,frame_apdu_t&,const ts_t& ts,const rts_t& /*rts*/ ){
	log().warnning( ts,THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_M_SP_TB_1( const frame_apdu_t&,frame_apdu_t&,const ts_t& ts,const rts_t& /*rts*/ ){
	log().warnning( ts,THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_M_DP_TB_1( const frame_apdu_t& /*rf*/,frame_apdu_t&,const ts_t& ts,const rts_t& /*rts*/ ){
	log().warnning( ts,THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_M_ST_TB_1( const frame_apdu_t&,frame_apdu_t&,const ts_t& ts,const rts_t& /*rts*/ ){
	log().warnning( ts,THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_M_BO_TB_1( const frame_apdu_t&,frame_apdu_t&,const ts_t& ts,const rts_t& /*rts*/ ){
	log().warnning( ts,THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_M_ME_TD_1( const frame_apdu_t&,frame_apdu_t&,const ts_t& ts,const rts_t& /*rts*/ ){
	log().warnning( ts,THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_M_ME_TE_1( const frame_apdu_t& /*rf*/,frame_apdu_t&,const ts_t& ts,const rts_t& /*rts*/ ){
	log().warnning( ts,THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_M_ME_TF_1( const frame_apdu_t& /*rf*/,frame_apdu_t&,const ts_t& ts,const rts_t& /*rts*/ ){
	log().warnning( ts,THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_M_IT_TB_1( const frame_apdu_t& /*rf*/,frame_apdu_t&,const ts_t& ts,const rts_t& /*rts*/ ){
	log().warnning( ts,THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_M_EP_TD_1( const frame_apdu_t&,frame_apdu_t&,const ts_t& ts,const rts_t& /*rts*/ ){
	log().warnning( ts,THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_M_EP_TE_1( const frame_apdu_t&,frame_apdu_t&,const ts_t& ts,const rts_t& /*rts*/ ){
	log().warnning( ts,THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_M_EP_TF_1( const frame_apdu_t&,frame_apdu_t&,const ts_t& ts,const rts_t& /*rts*/ ){
	log().warnning( ts,THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_C_SC_NA_1( const frame_apdu_t&,frame_apdu_t&,const ts_t& ts,const rts_t& /*rts*/ ){
	log().warnning( ts,THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_C_DC_NA_1( const frame_apdu_t&,frame_apdu_t& ,const ts_t& ts,const rts_t& /*rts*/ ){
	log().warnning( ts,THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_C_RC_NA_1( const frame_apdu_t&,frame_apdu_t& ,const ts_t& ts,const rts_t& /*rts*/ ){
	log().warnning( ts,THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_C_SE_NA_1( const frame_apdu_t&,frame_apdu_t& ,const ts_t& ts,const rts_t& /*rts*/ ){
	log().warnning( ts,THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_C_SE_NB_1( const frame_apdu_t&,frame_apdu_t& ,const ts_t& ts,const rts_t& /*rts*/ ){
	log().warnning( ts,THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_C_SE_NC_1( const frame_apdu_t&,frame_apdu_t& ,const ts_t& ts,const rts_t& /*rts*/ ){
	log().warnning( ts,THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_C_BO_NA_1( const frame_apdu_t& ,frame_apdu_t& ,const ts_t& ts,const rts_t& /*rts*/ ){
	log().warnning( ts,THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_C_SC_NA_1_7( const frame_apdu_t& ,frame_apdu_t& ,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().warnning( THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_C_DC_NA_1_7( const frame_apdu_t& ,frame_apdu_t& ,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().warnning( THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_C_RC_NA_1_7( const frame_apdu_t& ,frame_apdu_t& ,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().warnning( THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_C_SE_TA_1_7( const frame_apdu_t& ,frame_apdu_t& ,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().warnning( THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_C_SE_TB_1_7( const frame_apdu_t& ,frame_apdu_t& ,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().warnning( THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_C_SE_TC_1_7( const frame_apdu_t& ,frame_apdu_t& ,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().warnning( THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_C_BO_NA_1_7( const frame_apdu_t& ,frame_apdu_t& ,const ts_t& /*ts*/,const rts_t& /*rts*/  ){
	log().warnning( THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_M_EI_NA_1( const frame_apdu_t& ,frame_apdu_t& ,const ts_t& /*ts*/,const rts_t& /*rts*/  ){
	log().warnning( THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_C_IC_NA_1( const frame_apdu_t& ,frame_apdu_t& ,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().warnning( THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_C_CI_NA_1( const frame_apdu_t& ,frame_apdu_t& ,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().warnning( THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_C_RD_NA_1( const frame_apdu_t& ,frame_apdu_t& ,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().warnning( THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_C_CS_NA_1( const frame_apdu_t& ,frame_apdu_t& ,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().warnning( THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_C_RP_NA_1( const frame_apdu_t& ,frame_apdu_t& ,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().warnning( THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_C_TS_NA_1( const frame_apdu_t& ,frame_apdu_t& ,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().warnning( THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_P_ME_NA_1( const frame_apdu_t& ,frame_apdu_t& ,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().warnning( THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_P_ME_NB_1( const frame_apdu_t& ,frame_apdu_t& ,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().warnning( THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_P_ME_NC_1( const frame_apdu_t& ,frame_apdu_t& ,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().warnning( THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_P_AC_NA_1( const frame_apdu_t& ,frame_apdu_t& ,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().warnning( THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_F_FR_NA_1( const frame_apdu_t& ,frame_apdu_t& ,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().warnning( THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_F_SR_NA_1( const frame_apdu_t& ,frame_apdu_t& ,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().warnning( THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_F_SC_NA_1( const frame_apdu_t& ,frame_apdu_t& ,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().warnning( THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_F_LS_NA_1( const frame_apdu_t& ,frame_apdu_t& ,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().warnning( THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_F_AF_NA_1( const frame_apdu_t& ,frame_apdu_t& ,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().warnning( THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_F_SG_NA_1( const frame_apdu_t& ,frame_apdu_t& ,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().warnning( THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::dealAsdu_F_DR_NA_1( const frame_apdu_t& ,frame_apdu_t& ,const ts_t& /*ts*/,const rts_t& /*rts*/ ){
	log().warnning( THISMODULE "不支持的类型" );
	return Action_Nothing;
}

CIec104::EAction CIec104::needConfirmRsq(){
	log().debug(THISMODULE "发送S帧 %d->%d",m_rsqCfm.v(),m_rsq.v());
	txFrame().setSFrame();
	txFrame().setRecvSeq(m_rsq);
	m_rsqCfm = m_rsq;

	return Action_SendAndReTime;
}

void CIec104::setSendSeq(){
	txFrame().setSendSeq( m_ssq );
	++m_ssq;
}

void CIec104::setRecvConfSeq( const ts_t& /*ts*/,const rts_t& rts ){
	txFrame().setRecvSeq( m_rsq );
	m_rsqCfm = m_rsq;
	m_lastSendConfirmTime = rts;
}

void CIec104::getCurrentTime( frame_apdu_t::UCp56Time2a& t )const{
	std::time_t n = std::time(NULL);
	std::tm* tm = std::gmtime(&n);

	t.bits.year = tm->tm_year-2000;
	t.bits.mon = tm->tm_mon;
	t.bits.day = tm->tm_mday;
	t.bits.wday = tm->tm_wday;
	t.bits.hour = tm->tm_hour;
	t.bits.min = tm->tm_min;
	t.bits.ms = tm->tm_sec*1000;
}

bool CIec104::setCurrentTime( const frame_apdu_t::UCp56Time2a& t ){
	char cmd[56];
	sprintf(cmd,"date -s %04d-%02d-%02d %02d:%02d:%02d",t.bits.year+2000,t.bits.mon,t.bits.day,
			t.bits.hour,t.bits.min,t.bits.ms/1000);
	log().info(THISMODULE "执行对时指令 %s",cmd);
	system(cmd);

	return true;
}

}
}
